﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace KorkolaskuriBL
{
    public enum LoanType
    {
        EqualPrincipalPortion,      // tasalyhennyslaina
        EqualTotalPayment,          // annuiteettilaina
    }


    public class LoanViewModel : INotifyPropertyChanged
    {
        ObservableCollection<IPaymentStrategy> paymentStrategies = new ObservableCollection<IPaymentStrategy>();
        IPaymentStrategy paymentStrategy;

        double initialBalance;
        double interestRate;
        int interestPeriods;
        int paymentPeriods;
        double periodicPayment;
        ObservableCollection<LoanPayment> payments = new ObservableCollection<LoanPayment>();
        double totalInterestPaid;

        #region Properties

        public ObservableCollection<IPaymentStrategy> PaymentStrategies
        {
            get { return paymentStrategies; }
        }

        public IPaymentStrategy PaymentStrategy
        {
            get { return paymentStrategy; }
            set
            {
                paymentStrategy = value;
                OnPropertyChanged("PaymentStrategy");
                OnPropertyChanged("HasPaymentStrategy");
            }
        }

        public bool HasPaymentStrategy
        {
            get { return paymentStrategy != null; }
        }

        public double InitialBalance
        {
            get { return initialBalance; }
            set
            {
                initialBalance = value;
                OnPropertyChanged("InitialBalance");
            }
        }

        public double InterestRate
        {
            get { return interestRate; }
            set
            {
                interestRate = value;
                OnPropertyChanged("InterestRate");
            }
        }

        public int InterestPeriods
        {
            get { return interestPeriods; }
            set
            {
                interestPeriods = value;
                OnPropertyChanged("InterestPeriods");
            }
        }

        public int PaymentPeriods
        {
            get { return paymentPeriods; }
            set
            {
                paymentPeriods = value;
                OnPropertyChanged("PaymentPeriods");
            }
        }

        public double PeriodicPayment
        {
            get { return periodicPayment; }
            set
            {
                periodicPayment = value;
                OnPropertyChanged("PeriodicPayment");
            }
        }

        public ObservableCollection<LoanPayment> Payments
        {
            get { return payments; }
        }

        public double TotalInterestPaid
        {
            get { return totalInterestPaid; }
        }

        #endregion

        #region INotifyPropertyChanged interface

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        public void AddPaymentStrategy(IPaymentStrategy strategy)
        {
            paymentStrategies.Add(strategy);
        }


        public void CalculatePeriodicPayment()
        {
            if (paymentStrategy != null) {
                periodicPayment = paymentStrategy.CalculatePeriodicPayment(
                    initialBalance, interestRate, interestPeriods, paymentPeriods);
                OnPropertyChanged("PeriodicPayment");
            }
        }

        public void CalculatePaymentPeriods()
        {
            if (paymentStrategy != null) {
                paymentPeriods = paymentStrategy.CalculatePaymentPeriods(
                    initialBalance, interestRate, interestPeriods, periodicPayment);
                OnPropertyChanged("PaymentPeriods");
            }
        }

        public void CalculatePayments()
        {
            if (paymentStrategy != null) {
                payments.Clear();
                totalInterestPaid = 0;
                foreach (var p in paymentStrategy.CalculatePayments(
                    initialBalance, interestRate, interestPeriods, paymentPeriods, periodicPayment)) {
                    payments.Add(p);
                    totalInterestPaid += p.InterestPortion;
                }
                OnPropertyChanged("Payments");
                OnPropertyChanged("TotalInterestPaid");
            }
        }
    }
}
